package com.byx.chatclient.view.fragment;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import com.byx.chatclient.presenter.BasePresenter;
import com.byx.chatclient.view.IBaseView;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * BaseFragment
 *
 * @author Superb
 * @date 2021/3/24 22:49
 */
public abstract class BaseFragment<P extends BasePresenter> extends Fragment implements IBaseView {
    protected static final String TAG = BaseFragment.class.getSimpleName();

    protected P presenter;

    private Unbinder unbinder;

    private int layoutResId;

    private View layoutView;

    /**
     * Called when a fragment is first attached to its context.
     * {@link #onCreate(Bundle)} will be called after this.
     *
     * @param context
     */
    @Override
    public void onAttach(@NonNull Context context) {
        presenter = createPresenter();
        super.onAttach(context);
    }

    protected abstract P createPresenter();

    /**
     * Called to have the fragment instantiate its user interface view.
     * This is optional, and non-graphical fragments can return null. This will be called between
     * {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}.
     * <p>A default View can be returned by calling {@link # Fragment(int)} in your
     * constructor. Otherwise, this method returns null.
     *
     * <p>It is recommended to <strong>only</strong> inflate the layout in this method and move
     * logic that operates on the returned View to {@link #onViewCreated(View, Bundle)}.
     *
     * <p>If you return a View from here, you will later be called in
     * {@link #onDestroyView} when the view is being released.
     *
     * @param inflater           The LayoutInflater object that can be used to inflate
     *                           any views in the fragment,
     * @param container          If non-null, this is the parent view that the fragment's
     *                           UI should be attached to.  The fragment should not add the view itself,
     *                           but this can be used to generate the LayoutParams of the view.
     * @param savedInstanceState If non-null, this fragment is being re-constructed
     *                           from a previous saved state as given here.
     * @return Return the View for the fragment's UI, or null.
     */
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        setRootView(savedInstanceState);
        if(layoutView == null) {
            if(layoutResId != 0) {
                layoutView = inflater.inflate(layoutResId, container, false);
            }
        }
        unbinder = ButterKnife.bind(this, layoutView);

        initialize();
        setListeners();
        return layoutView;
    }

    /**
     * Called when the fragment's activity has been created and this
     * fragment's view hierarchy instantiated.  It can be used to do final
     * initialization once these pieces are in place, such as retrieving
     * views or restoring state.  It is also useful for fragments that use
     * {@link #setRetainInstance(boolean)} to retain their instance,
     * as this callback tells the fragment when it is fully associated with
     * the new activity instance.  This is called after {@link #onCreateView}
     * and before {@link #onViewStateRestored(Bundle)}.
     *
     * @param savedInstanceState If the fragment is being re-created from
     *                           a previous saved state, this is the state.
     */
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        activityCreate(savedInstanceState);
    }

    /**
     * Called when the Fragment is visible to the user.  This is generally
     * tied to {@link Activity# onStart() Activity.onStart} of the containing
     * Activity's lifecycle.
     */
    @Override
    public void onStart() {
        super.onStart();
        if (presenter != null) {
            presenter.attachView(this);
        }
        start();
    }

    @Override
    public void onResume() {
        super.onResume();
        resume();
    }

    protected void resume(){}

    @Override
    public void onPause() {
        super.onPause();
        pause();
    }

    protected void pause(){}

    @Override
    public void onStop() {
        super.onStop();
        stop();
    }

    protected void stop(){}

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        destroyView();
    }

    protected void destroyView(){}

    @Override
    public void onDestroy() {
        if (presenter != null) {
            presenter.detachView();
        }

        if (unbinder != null) {
            unbinder.unbind();
            unbinder = null;
        }
        destroy();
        super.onDestroy();
    }

    protected void destroy(){}

    @Override
    public void onDetach() {
        super.onDetach();
        detach();
    }

    protected void detach() {}

    protected void start(){}

    protected void activityCreate(Bundle savedInstanceState){}

    protected abstract void initialize();

    protected abstract void setListeners();

    protected abstract void setRootView(Bundle savedInstanceState);

    protected void setLayoutResId(int layoutResId) {
        this.layoutResId = layoutResId;
    }

    protected void setLayoutView(View layoutView) {
        this.layoutView = layoutView;
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void toastQuick(String msg) {
        Toast.makeText(getContext(),msg,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void toastSlow(String msg) {
        Toast.makeText(getContext(),msg,Toast.LENGTH_LONG).show();
    }
}
